package com.qk.management.aspect;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.qk.code.BusinessEnum;
import com.qk.management.annotation.RedisCacheable;
import com.qk.result.Result;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

/**
 * @Author:zhengbowen
 * @Date: 2025/10/18 10:08
 * @Description:
 */
@Aspect
@Slf4j
@Component
@RequiredArgsConstructor
@SuppressWarnings("all")
public class CacheableAspect {

    private final StringRedisTemplate stringRedisTemplate;

    @Pointcut("@annotation(com.qk.management.annotation.RedisCacheable)")
    public void cacheable() {
    }

    @Around("cacheable()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = null;
        String key= null;
        long expire=0;
        TimeUnit expireTimeFormat= TimeUnit.SECONDS;
        try {
            //从注解中获取注解信息
            Class<?> aClass = joinPoint.getTarget().getClass();
            //获取方法名称
            // 修改为
            Signature signature = joinPoint.getSignature();
            String methodName = signature.getName();
            Method method = aClass.getMethod(methodName);
            //获取注解信息
            RedisCacheable annotation = method.getAnnotation(RedisCacheable.class);
            String prefix = annotation.prefix();
            expireTimeFormat = annotation.expireTimeFormat();
            expire = annotation.expire();
            //拼接prefix与注解的方法名
            key = prefix + methodName;
            //获取缓存信息
            String jsonStr = stringRedisTemplate.opsForValue().get(key);
            if(ObjectUtil.isNotEmpty(jsonStr)){
                return JSONUtil.toBean(jsonStr, method.getReturnType());
            }
        } catch (Exception e) {
            log.error("获取缓存信息异常:{}", e.getMessage());
        }
        //缓存未命中
        try {
            result = joinPoint.proceed();
        } catch (Throwable e) {
            return Result.error(BusinessEnum.BUSINESS_ERROR);
        }
        // 将数据加入缓存
        try {
            stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(result), expire, expireTimeFormat);
        } catch (Exception e) {
            log.error("缓存异常:{}", e.getMessage());
        }
        return result;
    }
}
